from flask import Flask, request, jsonify
import json
import sys
import urllib.parse
import pandas as pd
import re
app = Flask(__name__)

def cal_A1(x):
    return min(x,5)/5

def cal_A21(vote_record):
    # 限定阶段为 CD及以前
    data = vote_record[vote_record['阶段'] == 'CD及以前'].copy()
    # 投票权重
    weight_map = {'没意见': 0.4, '有意见': 1.0}
    data['权重'] = data['投票意见'].map(weight_map)
    # 计算分子 -- 中国
    china_sum = data[data['国籍'] == '中国']['权重'].sum()
    # 计算分母 -- 所有
    total_sum = data['权重'].sum()
    # 计算结果
    return china_sum / total_sum if total_sum != 0 else 0

def cal_A22_A23(vote_record,stageType):
    # stageType 为  DIS/FDIS
    data = vote_record[vote_record['阶段'] == stageType].copy()
    # 投票权重
    weight_map = {'赞成没意见':0.6,'赞成有意见':1.0,'弃权':0.2,'反对':1.0}
    data['权重'] = data['投票意见'].map(weight_map)
    # 计算分子 -- 中国
    china_sum = data[data['国籍'] == '中国']['权重'].sum()
    # 计算分母 -- 所有
    total_sum = data['权重'].sum()
    # 计算结果
    return china_sum / total_sum if total_sum != 0 else 0

def cal_A3_all(meeting_record, stageType):
    # stageType 为  CD及以前/DIS/FDIS
    data = meeting_record[meeting_record['阶段'] == stageType].copy()
    # 投票权重
    weight_map = {'参与没意见':0.6,'线上参与有意见':0.8,'线下参与有意见':1.0,'线上参与并有反对意见':0.8,'线下参与并有反对意见':1.0,'没参与':0.2}
    data['权重'] = data['参会意见'].map(weight_map)
    # 计算分子 -- 中国
    china_sum = data[data['参会国家'] == '中国']['权重'].sum()
    # 计算分母 -- 所有
    total_sum = data['权重'].sum()
    # 计算结果
    return china_sum / total_sum if total_sum != 0 else 0

def cal_A4_all(x):
    if x==0 :return 0
    elif x==1 or x==2 : return 0.6
    elif x>=3: return 1.0

def cal_B1_all(vote_record,meeting_record,stageType):
    vote_data = vote_record[vote_record['阶段'] == stageType].copy()
    meeting_data = meeting_record[meeting_record['阶段'] == stageType].copy()

    vote_sum = vote_data['意见数量'].sum()
    meeting_sum = meeting_data['意见数量'].sum()
    return vote_sum/(vote_sum + meeting_sum)

def cal_weight_adoption_for_B2_B4(adoption_str):
    weight_map = {'Technical': 1.0, 'General': 0.6, 'Editorial': 0.2}
    # 检查输入是否为字符串，如果不是则将其转换为字符串
    if pd.isna(adoption_str) or adoption_str == '' or not isinstance(adoption_str, str):
        return 0
    # 将采纳情况拆分成字典
    adoption_dict = dict(item.split(":") for item in adoption_str.split(","))
    # 计算加权采纳意见
    weighted_sum = sum(int(adoption_dict[k]) * weight for k, weight in weight_map.items())
    return weighted_sum

def cal_B2_all(vote_record, stageType):
    # stageType 为  CD及以前/DIS/FDIS
    data = vote_record[vote_record['阶段'] == stageType].copy()
    # 采纳意见的加权值
    data['加权采纳意见'] = data['采纳情况'].apply(cal_weight_adoption_for_B2_B4)

    # 中国-采纳意见加权和
    china_res = data[data['国籍']=='中国']['加权采纳意见'].sum()
    # 所有-采纳意见加权和
    total_res = data['加权采纳意见'].sum()
    # 计算结果
    return china_res / total_res if total_res != 0 else 0

def cal_B3_all(meeting_record, stageType):
    # stageType 为  CD及以前/DIS/FDIS
    data = meeting_record[meeting_record['阶段'] == stageType].copy()
    # 中国参与的会议数
    china_meetings_count = data[data['参会国家'] == '中国']['会议轮次'].nunique()
    # 总会议数
    total_meetings_count = data['会议轮次'].nunique()

    # 4. 返回结果
    return china_meetings_count/total_meetings_count

def cal_B4_all(meeting_record, stageType):
    # stageType 为  CD及以前/DIS/FDIS
    data = meeting_record[meeting_record['阶段'] == stageType].copy()
    # 采纳意见的加权值
    data['加权采纳意见'] = data['采纳情况'].apply(cal_weight_adoption_for_B2_B4)

    # 中国-采纳意见加权和
    china_res = data[data['国籍'] == '中国']['加权采纳意见'].sum()
    # 所有-采纳意见加权和
    total_res = data['加权采纳意见'].sum()
    # 计算结果
    return china_res / total_res if total_res != 0 else 0

def cal_B5_all(x):
    if x>0: return 1.0
    elif x==0: return 0.0

def cal_C(vote_record,meeting_record):
    vote_data = vote_record.copy()
    meeting_data = meeting_record.copy()
    # 采纳意见的加权值
    vote_data['加权采纳意见'] = vote_data['采纳情况'].apply(cal_weight_adoption_for_B2_B4)
    meeting_data['加权采纳意见'] = meeting_data['采纳情况'].apply(cal_weight_adoption_for_B2_B4)

    # 中国-采纳意见加权和
    china_res_vote = vote_data[vote_data['国籍'] == '中国']['加权采纳意见'].sum()
    china_res_meeting = meeting_data[meeting_data['国籍'] == '中国']['加权采纳意见'].sum()
    china_res = china_res_vote + china_res_meeting
    # 所有-采纳意见加权和
    total_res_vote = vote_data['加权采纳意见'].sum()
    total_res_meeting = meeting_data['加权采纳意见'].sum()
    total_res = total_res_vote + total_res_meeting
    # 计算结果
    return china_res / total_res if total_res != 0 else 0


def extract_parts(s): # 把三级指标名 ——> 二级指标 + 1/2/3
    match = re.match(r'([A-Z]\d)(\d+)', s)
    if match:
        part1 = match.group(1)  # 第一个字母和数字的组合
        part2 = match.group(2)  # 第二个数字
        return part1, part2
    else:
        return None


@app.route('/calCNJoin', methods=['POST'])
def calculate():
    try:
        data = request.json
        target = data.get("target")
        x = data.get("x")
        vote_record_path = data.get("vote_record_path")
        meeting_record_path = data.get("meeting_record_path")

        vote_record = None
        meeting_record = None

        if vote_record_path:
            vote_record = pd.read_excel(vote_record_path, engine='openpyxl')
        if meeting_record_path:
            meeting_record = pd.read_excel(meeting_record_path, engine='openpyxl')

        target, level3 = extract_parts(target)
        stageTypeMap = {'1': "CD及以前", '2': "DIS", '3': "FDIS"}
        stageType = stageTypeMap.get(level3)

        if target == 'A1':
            return jsonify({"calRes": cal_A1(int(x))})
        elif target == 'A2':
            if stageType == 'CD及以前':
                return jsonify({"calRes": cal_A21(vote_record)})
            else:
                return jsonify({"calRes": cal_A22_A23(vote_record, stageType)})
        elif target == 'A3':
            return jsonify({"calRes": cal_A3_all(meeting_record, stageType)})
        elif target == 'A4':
            return jsonify({"calRes": cal_A4_all(int(x))})
        elif target == 'B1':
            return jsonify({"calRes": cal_B1_all(vote_record, meeting_record, stageType)})
        elif target == 'B2':
            return jsonify({"calRes": cal_B2_all(vote_record, stageType)})
        elif target == 'B3':
            return jsonify({"calRes": cal_B3_all(meeting_record, stageType)})
        elif target == 'B4':
            return jsonify({"calRes": cal_B4_all(meeting_record, stageType)})
        elif target == 'B5':
            return jsonify({"calRes": cal_B5_all(int(x))})
        elif target == 'C1':
            return jsonify({"calRes": cal_C(vote_record, meeting_record)})
        else:
            return jsonify({"calRes": "Invalid target"}), 400
    except Exception as e:
        return jsonify({"calRes": str(e)}), 500

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=5001)